#include "LineSegment.h"

LineSegment::LineSegment()
{
    this->set_dimensao(0);
}

LineSegment::LineSegment(const Point& p_inicio, const Point& p_fim)
{
    // Se os dois pontos passados tiverem a mesma dimensão:
    if (p_inicio.get_dimensao() == p_fim.get_dimensao())
    {
        this->set_dimensao(p_inicio.get_dimensao());
        this->i = p_inicio;
        this->f = p_fim;
        return;
    }
	this->set_dimensao(0);
}

LineSegment::~LineSegment(){}

void LineSegment::imprimir() const
{
    i.imprimir();
    cout<<"--->";
    f.imprimir();
}

void LineSegment::set_dimensao(size_t d)
{
    this->dimensao = d;
}

size_t LineSegment::get_dimensao() const
{
    return(this->dimensao);
}

TIPO_ELEMENTO LineSegment::comprimento() const
{
    return((f - i).norma());
}

TIPO_ELEMENTO LineSegment::area_triangulo(const Point& p) const
{
    Vector v1 = p.paraVector();
    Vector v2 = i.paraVector();
    Vector v3 = f.paraVector();
    // S = (1/2) * (p1 x p2 + p2 x p3 + p3 x p1)
    return(((0.5)*(v1*v2 + v2*v3 + v3*v1)).norma());
}

TIPO_ELEMENTO LineSegment::distancia(const Point& p) const
{
    return(2*(area_triangulo(p)/comprimento()));
}

bool LineSegment::intercepta(const LineSegment& s) const
{
    // Se for o mesmo segmento:
    if (this == &s) return(true);
    // Primeira equação:
    Vector ab = getF()   - getI();
    Vector ac = s.getI() - getI();
    Vector ad = s.getF() - getI();
    // Segunda equação:
    Vector cd = s.getF() - s.getI();
    Vector ca = getI()   - s.getI();
    Vector cb = getF()   - s.getI();
    // Os segmentos se interceptam se, e somente se:
    return((((ab * ac)^(ab * ad)) < 0) && (((cd * ca)^(cd * cb)) < 0));
}
